﻿namespace MEF_Test.Bricks.MediaBrowser
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;

    using MEF_Test.Contracts;

    using Microsoft.Practices.Prism.Commands;

    public class MediaBrowserViewModel : INotifyPropertyChanged
    {
        #region Constants and Fields

        /// <summary>
        /// The name of the <see cref="Children"/> property.
        /// </summary>
        private static readonly string _childrenPropertyName = PropertyHelper.MemberName<MediaBrowserViewModel>(o => o.Children);

        /// <summary>
        /// The name of the <see cref="DetailViewModel"/> property.
        /// </summary>
        private static readonly string _detailViewModelPropertyName = PropertyHelper.MemberName<MediaBrowserViewModel>(o => o.DetailViewModel);

        /// <summary>
        /// The backing field for the <see cref="Children"/> property.
        /// </summary>
        private ObservableCollection<IBrowserNodeViewModel> _children;

        /// <summary>
        /// The backing field for the <see cref="DetailViewModel"/> property.
        /// </summary>
        private IBrowserDetailViewModel _detailViewModel;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="MediaBrowserViewModel"/> class.
        /// </summary>
        public MediaBrowserViewModel()
        {
            SelectedNodeChangedCommand = new DelegateCommand<IBrowserNodeViewModel>(selectedNodeChanged);
        }

        #endregion

        #region Events

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the children.
        /// </summary>
        /// <value>The children.</value>
        public ObservableCollection<IBrowserNodeViewModel> Children 
        {
            get
            {
                if (_children == null)
                {
                    throw new InvalidOperationException("The GetCurrentChildren method has not been called on this Node. Please, do so before querying the Children property");
                }

                return _children;
            }

            set
            {
                if (_children != value)
                {
                    _children = value;

                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs(_childrenPropertyName));
                    }
                }
            }
        }

        /// <summary>
        /// Gets or sets the detail view.
        /// </summary>
        /// <value>The detail view.</value>
        public IBrowserDetailViewModel DetailViewModel
        {
            get
            {
                return _detailViewModel;
            }

            set
            {
                _detailViewModel = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(_detailViewModelPropertyName));
                }
            }
        }

        /// <summary>
        /// Gets or sets the selected node changed command.
        /// </summary>
        /// <value>The selected node changed command.</value>
        public DelegateCommand<IBrowserNodeViewModel> SelectedNodeChangedCommand { get; set; }

        #endregion

        #region Methods

        /// <summary>
        /// Occurs after the selected node is changed.
        /// </summary>
        /// <param name="selectedNode">The selected node.</param>
        private void selectedNodeChanged(IBrowserNodeViewModel selectedNode)
        {
            this.DetailViewModel = selectedNode.CreateDetailViewModel();
        }

        #endregion
    }
}
